﻿using log4net;
using System;
using System.Data.Common;
using System.IO;

namespace per.esmool.utils.DB {

    public abstract class Dao<T, TC> 
        where T : IIDData<T>, new() 
        where TC : DbConnection
    {

        private static readonly ILog LOG = LogManager.GetLogger(typeof(Dao<T, TC>));

        public Dao() { }

        public IDbManager<TC> Manager { get; set; }

        protected virtual C CreateCommand<C, TT>(string sql, TT transaction = null)
            where C : DbCommand, new()
            where TT : DbTransaction {
            var cmd = new C() {
                CommandText = sql,
                Connection = Manager.Connection,
                Transaction = transaction
            };
            return cmd;
        }

        protected virtual void PutParameter<C, P>(C cmd, P parameter)
            where C : DbCommand
            where P : DbParameter {
            cmd.Parameters.Add(parameter);
        }

        public void RunTransaction<TR>(Action<TR> action) where TR : DbTransaction {
            try {
                using TR transaction = Manager.Connection.BeginTransaction() as TR;
                try {
                    action.Invoke(transaction);
                    transaction.Commit();
                } catch (Exception err) {
                    transaction.Rollback();
                    throw new IOException("Cannot perform transaction", err);
                }
            } catch (DbException err) {
                throw new IOException("Cannot perform transaction", err);
            }
        }

    }
}
